﻿
using CSharpLibs.Annotations;

namespace System.Collections
{
	[Builtin]
	public sealed class BitArray : ICollection, IEnumerable
	{
		private bool[] m_array;
		
		private BitArray()
		{ ;}

		public BitArray(int length)
		{ this.m_array = new bool[length]; }

		public BitArray(BitArray bits)
		{ this.m_array = (bool[])bits.m_array.Clone(); }

		public BitArray(bool[] values)
		{ this.m_array = (bool[])values.Clone(); }

		public BitArray And(BitArray value)
		{
			for(int i = 0; i < this.m_array.Length; i++)
				this.m_array[i] &= value.m_array[i];
			
			return this;
		}

		public void CopyTo(bool[] array, int index)
		{
			bool[] flagArray = (bool[])array;
			for(int j = 0; j < this.m_array.Length; j++)
				flagArray[index + j] = this.m_array[j];
		}

		public bool Get(int index)
		{ return this.m_array[index]; }

		public IEnumerator GetEnumerator()
		{ return new BitArrayEnumeratorSimple(this); }

		public BitArray Not()
		{
			for(int i = 0; i < this.m_array.Length; i++)
				this.m_array[i] = !this.m_array[i];
			
			return this;
		}

		public BitArray Or(BitArray value)
		{
			for(int i = 0; i < this.m_array.Length; i++)
				this.m_array[i] |= value.m_array[i];
			
			return this;
		}

		public void Set(int index, bool value)
		{ this.m_array[index] = value; }

		public void SetAll(bool value)
		{
			for(int i = 0; i < this.m_array.Length; i++)
				this.m_array[i] = value;
		}

		public BitArray Xor(BitArray value)
		{
			for(int i = 0; i < this.m_array.Length; i++)
				this.m_array[i] ^= value.m_array[i];
		
			return this;
		}

		// Properties
		public int Count
		{ get { return this.m_array.Length; } }

		public bool this[int index]
		{
			get { return this.Get(index); }

			set { this.Set(index, value); }
		}

		public int Length
		{ get { return this.m_array.Length; } }

		private class BitArrayEnumeratorSimple : IEnumerator
		{
			private BitArray bitarray;
			private bool currentElement;
			private int index;
			
			internal BitArrayEnumeratorSimple(BitArray bitarray)
			{
				this.bitarray = bitarray;
				this.index = -1;
			}

			public bool MoveNext()
			{
				if(this.index < (this.bitarray.Count - 1))
				{
					this.index++;
					this.currentElement = this.bitarray.Get(this.index);
					return true;
				}
				this.index = this.bitarray.Count;
				return false;
			}

			public void Reset()
			{ this.index = -1; }

			public object Current
			{
				get	{ return this.currentElement; }
			}
		}
	}
}
